#第十八章 使用asyncio包处理并发

#使用asyncio处理并发

import asyncio
import sys
import time
import itertools

#asyncio.sleep(0.1) 返回的也是一个生成器 相对于子生成器 spin本身是一个委派生成器
'''
下列代码中大量使用了 yield from asyncio.sleep(0.1) 这样的表达式 就是因为这样可以使得线程阻塞（挂起、暂停？）然后执行下一个线程
从而达到异步执行 挂起的线程会在 asyncio.sleep(0.1) 执行完成后重新执行
'''


@asyncio.coroutine  #异步协程装饰器
def spin(msg):
    write,flush = sys.stdout.write,sys.stdout.flush
    
    for char in itertools.cycle("|-/\\"):
        status = char + " " + msg        
        write(status)
        flush()
        s = '\x08'*len(status)
        write(s)
        try:
            yield from asyncio.sleep(0.1) 
        except asyncio.CancelledError:
            break
    write(" "*len(status)+s)


@asyncio.coroutine
def slow_fun():
    yield from asyncio.sleep(3)
    return 42

@asyncio.coroutine
def supervisor():
    spinner = asyncio.async(spin("thinking!"))
    print("spinner object:",spinner)    
    result = yield from slow_fun()
    spinner.cancel()
    return result

def main():
    loop = asyncio.get_event_loop()
    result = loop.run_until_complete(supervisor())
    loop.close()
    print("Answer:",result)

if __name__ == "__main__":
    print("....",asyncio.sleep(.1)) #返回一个生成器
    print("-------",time.sleep(0.1)) #返回None    
    main()